﻿var path = require('path'),
    Webpack = require('webpack'),
    merge = require('webpack-merge'),
    HtmlWebpackPlugin = require('html-webpack-plugin'),
    ExtractTextWebpackPlugin = require('extract-text-webpack-plugin'),
    CopyPlugin = require('copy-webpack-plugin'),
    baseConfig = require('./webpack.config.js'),
    CleanWebpackPlugin = require('clean-webpack-plugin'),
    publicPath = './';

// 清空 plugins
baseConfig.plugins = [];
module.exports = merge(baseConfig, {
    // 禁用缓存 - js
    output: {
        path: path.join(__dirname, '/dist/'),
        publicPath: publicPath, // 打包资源引入路径，相对于 html 于资源包的目录, css 可单独配置
        filename: 'js/[name].[chunkhash].js',
        chunkFilename: 'js/[name].[chunkhash].chunk.js' // 打包异步请求的文件
    },
    plugins: [
        // 打包完成后目录删除
        new CleanWebpackPlugin(
            ['dist'], // 删除的目录
            {
                verbose: true, // 在控制台显示删除操作
                dry: false // 是否禁用删除目录操作
                // exclude: ['test'] // 忽略的目录
            }
        ),

        // 静态文件拷贝插件
        new CopyPlugin([
            {
                from: './public/static/', // './' 目录相对于 path 目录
                to: './static/' // './' 目录相对于 path 目录
            }
        ]),

        // 定义开发环境变量
        new Webpack.DefinePlugin({
            'process.env': {
                NODE_ENV: JSON.stringify(process.env.NODE_ENV), // cross-env 传递的当前开发环境
                Mock: false // 使用启用 Mock 数据（仅开发环境配置为 true）
            }
        }),

        // css 提取
        new ExtractTextWebpackPlugin({
            filename: 'css/[name].[contenthash].css',
            allChunks: true // 把所有的异步请求的 .vue 文件的 style 也打包入主样式表, 有利有弊
        }),

        // 生成稳定的 moduleId
        new Webpack.HashedModuleIdsPlugin({
            hashFunction: 'sha256',
            hashDigest: 'hex',
            hashDigestLength: 20
        }),

        // 生成稳定的 chunkId 使用 chunk.name 生成 chunkId, 如下示例:
        // 如果固定非具名 chunk 块, 目前所知道的能通过 "魔法注释" import(/* webpackChunkName: 'views/test' */'.views/test').then() 实现
        // 需要先开启 .babelrc 的 comments: true 否则 "魔法注释" 会被移除, 打包时需要删除注释可以配置 Webpack.optimize.UglifyJsPlugin 的 output.comments: false
        new Webpack.NamedChunksPlugin(), // 该插件的内部实现就是通过将 chunk.id = chunk.name 实现

        // 抽离共有的 css 和 js 形成文件名
        new Webpack.optimize.CommonsChunkPlugin({
            names: ['vendor', 'manifest'], // 抽离 vendor 为入口配置的第三方库的数组集合, manifest 为 webpack 引用管理文件
            minChunks: Infinity // 设置为 Infinity 抽离第三方库文件
            // filename: 'js/common.js', // 对于需要抽离 manifest 这种 webapck 运行时的文件, 不要设置文件名, 否则每次打包文件指纹都会变
            // chunks: ['project1', 'project2'], // 针对多入口的时候使用, SPA 项目不用设置, 只需要把第三方库和 manifest 抽离即可
        }),

        // 通过模板生成打包后的 html 文件
        new HtmlWebpackPlugin({
            // 目录现对于环境根目录 ./public/template.html
            template: path.join(__dirname, '/public/template.html'),

            // 默认是 index.html
            // 目录相对于(绝对路径)
            filename: path.join(__dirname, '/dist/index.html'),

            // 默认是 true 插入到 body 底部
            inject: true,

            // 多文件入口 || 抽离文件缓存时, 选择性的引入文件
            // <script type="text/javascript" src="main.js"> <script type="text/javascript" src="index.js">
            // 引入的文件顺序 webpack 根据加载顺序自行排序
            chunks: ['manifest', 'vendor', 'main'],

            // 给 script & link 标签添加查询字符串禁止缓存
            hash: true,

            // 页面标题配置
            title: '测试系统',

            // 公共路径前缀，应对一些需要配置 externals 选项的模块引入统一设置路径，比如 echarts
            publicPath: publicPath,
            minify: {
                removeComments: true, // 针对模板文件
                collapseWhitespace: true // 针对模板文件
            }
        }),

        // 压缩 js & css
        new Webpack.optimize.UglifyJsPlugin({
            // 对压缩后的 js 开启 source-map: 设置为 'source-map'字符串值时打包会产生 source-map js 文件，压缩代码的报错可对应到具体行
            // 启用 UglifyJsPlugin 时，如果要启用 devtool: "source-map"，需要开启 UglifyJsPlugin 的 sourceMap 为 true
            sourceMap: true,
            output: {
                comments: false // 删除注释
            },
            compress: {
                warnings: false,
                drop_debugger: true,
                drop_console: true
                // pure_funcs: ['console.log'] // 使用 drop_console 能过滤掉所有 console.error/warn/info() 等方法
            }
        })
    ],
    // 启用 sourcemap（查看文件的源码）禁用时赋值为 false 即可
    devtool: 'source-map'
});